package agent

import (
	"context"
	"fmt"
	"log"
	"sort"
	"time"
)

// Executor 执行器
type Executor struct {
	tools   *ToolManager
	timeout time.Duration
}

// NewExecutor 创建新的执行器
func NewExecutor(tools *ToolManager, timeout time.Duration) *Executor {
	return &Executor{
		tools:   tools,
		timeout: timeout,
	}
}

// ExecutePlan 执行计划
func (e *Executor) ExecutePlan(ctx context.Context, plan *Plan) (*ExecutionResult, error) {
	log.Printf("[EXECUTOR] 🚀 开始执行计划: %s", plan.Description)
	
	startTime := time.Now()
	result := &ExecutionResult{
		PlanID:      plan.ID,
		Success:     true,
		ToolResults: make([]ToolResult, 0),
	}

	// 按顺序执行步骤
	sort.Slice(plan.Steps, func(i, j int) bool {
		return plan.Steps[i].Order < plan.Steps[j].Order
	})

	for i, step := range plan.Steps {
		log.Printf("[EXECUTOR] 📋 执行步骤 %d/%d: %s", i+1, len(plan.Steps), step.Description)
		
		stepResult, err := e.executeStep(ctx, step)
		if err != nil {
			log.Printf("[EXECUTOR] ❌ 步骤执行失败: %v", err)
			result.Success = false
			result.Error = err.Error()
			break
		}

		if stepResult != nil {
			result.ToolResults = append(result.ToolResults, *stepResult)
		}

		log.Printf("[EXECUTOR] ✅ 步骤执行成功")
	}

	result.Duration = time.Since(startTime)
	
	if result.Success {
		log.Printf("[EXECUTOR] ✅ 计划执行成功，耗时: %v", result.Duration)
	} else {
		log.Printf("[EXECUTOR] ❌ 计划执行失败，耗时: %v", result.Duration)
	}

	return result, nil
}

// executeStep 执行单个步骤
func (e *Executor) executeStep(ctx context.Context, step PlanStep) (*ToolResult, error) {
	// 创建带超时的上下文
	stepCtx, cancel := context.WithTimeout(ctx, e.timeout)
	defer cancel()

	switch step.Type {
	case "tool_call":
		return e.executeToolCall(stepCtx, step)
	case "llm_query":
		return e.executeLLMQuery(stepCtx, step)
	case "memory_search":
		return e.executeMemorySearch(stepCtx, step)
	default:
		return nil, fmt.Errorf("未知的步骤类型: %s", step.Type)
	}
}

// executeToolCall 执行工具调用
func (e *Executor) executeToolCall(ctx context.Context, step PlanStep) (*ToolResult, error) {
	log.Printf("[EXECUTOR] 🔧 执行工具调用: %s", step.ToolName)
	
	startTime := time.Now()
	
	// 获取工具
	tool, exists := e.tools.GetTool(step.ToolName)
	if !exists {
		return &ToolResult{
			ToolName:  step.ToolName,
			Success:   false,
			Error:     fmt.Sprintf("工具不存在: %s", step.ToolName),
			Duration:  time.Since(startTime),
			Timestamp: time.Now(),
		}, nil
	}

	// 验证参数
	if err := e.validateParameters(tool, step.Parameters); err != nil {
		return &ToolResult{
			ToolName:  step.ToolName,
			Success:   false,
			Error:     fmt.Sprintf("参数验证失败: %v", err),
			Duration:  time.Since(startTime),
			Timestamp: time.Now(),
		}, nil
	}

	// 执行工具
	output, err := tool.Handler(ctx, step.Parameters)
	duration := time.Since(startTime)

	if err != nil {
		log.Printf("[EXECUTOR] ❌ 工具执行失败: %v", err)
		return &ToolResult{
			ToolName:  step.ToolName,
			Success:   false,
			Error:     err.Error(),
			Duration:  duration,
			Timestamp: time.Now(),
		}, nil
	}

	log.Printf("[EXECUTOR] ✅ 工具执行成功，输出长度: %d", len(output))
	return &ToolResult{
		ToolName:  step.ToolName,
		Success:   true,
		Output:    output,
		Duration:  duration,
		Timestamp: time.Now(),
	}, nil
}

// executeLLMQuery 执行LLM查询
func (e *Executor) executeLLMQuery(ctx context.Context, step PlanStep) (*ToolResult, error) {
	log.Printf("[EXECUTOR] 🤖 执行LLM查询")
	
	startTime := time.Now()
	
	// LLM查询通常不需要在这里执行，因为它会在Agent的最终响应生成阶段处理
	// 这里只是标记为成功，实际的LLM调用在Agent.generateResponse中进行
	
	return &ToolResult{
		ToolName:  "llm_query",
		Success:   true,
		Output:    "LLM查询已准备就绪",
		Duration:  time.Since(startTime),
		Timestamp: time.Now(),
	}, nil
}

// executeMemorySearch 执行记忆搜索
func (e *Executor) executeMemorySearch(ctx context.Context, step PlanStep) (*ToolResult, error) {
	log.Printf("[EXECUTOR] 🧠 执行记忆搜索")
	
	startTime := time.Now()
	
	// 获取搜索参数
	_, ok := step.Parameters["query"].(string)
	if !ok {
		return &ToolResult{
			ToolName:  "memory_search",
			Success:   false,
			Error:     "缺少搜索关键词",
			Duration:  time.Since(startTime),
			Timestamp: time.Now(),
		}, nil
	}

	// 调用记忆搜索工具
	tool, exists := e.tools.GetTool("search_memory")
	if !exists {
		return &ToolResult{
			ToolName:  "memory_search",
			Success:   false,
			Error:     "记忆搜索工具不存在",
			Duration:  time.Since(startTime),
			Timestamp: time.Now(),
		}, nil
	}

	output, err := tool.Handler(ctx, step.Parameters)
	duration := time.Since(startTime)

	if err != nil {
		return &ToolResult{
			ToolName:  "memory_search",
			Success:   false,
			Error:     err.Error(),
			Duration:  duration,
			Timestamp: time.Now(),
		}, nil
	}

	return &ToolResult{
		ToolName:  "memory_search",
		Success:   true,
		Output:    output,
		Duration:  duration,
		Timestamp: time.Now(),
	}, nil
}

// validateParameters 验证工具参数
func (e *Executor) validateParameters(tool *Tool, params map[string]interface{}) error {
	// 检查必需参数
	for paramName, paramDef := range tool.Parameters {
		if paramDefMap, ok := paramDef.(map[string]interface{}); ok {
			if required, exists := paramDefMap["required"]; exists && required.(bool) {
				if _, hasParam := params[paramName]; !hasParam {
					return fmt.Errorf("缺少必需参数: %s", paramName)
				}
			}
		}
	}

	// 可以添加更多的参数类型验证逻辑
	return nil
}

// ExecuteToolDirectly 直接执行工具（用于简单的工具调用）
func (e *Executor) ExecuteToolDirectly(ctx context.Context, toolName string, params map[string]interface{}) (*ToolResult, error) {
	log.Printf("[EXECUTOR] 🔧 直接执行工具: %s", toolName)
	
	startTime := time.Now()
	
	tool, exists := e.tools.GetTool(toolName)
	if !exists {
		return &ToolResult{
			ToolName:  toolName,
			Success:   false,
			Error:     fmt.Sprintf("工具不存在: %s", toolName),
			Duration:  time.Since(startTime),
			Timestamp: time.Now(),
		}, nil
	}

	// 验证参数
	if err := e.validateParameters(tool, params); err != nil {
		return &ToolResult{
			ToolName:  toolName,
			Success:   false,
			Error:     fmt.Sprintf("参数验证失败: %v", err),
			Duration:  time.Since(startTime),
			Timestamp: time.Now(),
		}, nil
	}

	// 创建带超时的上下文
	toolCtx, cancel := context.WithTimeout(ctx, e.timeout)
	defer cancel()

	// 执行工具
	output, err := tool.Handler(toolCtx, params)
	duration := time.Since(startTime)

	if err != nil {
		return &ToolResult{
			ToolName:  toolName,
			Success:   false,
			Error:     err.Error(),
			Duration:  duration,
			Timestamp: time.Now(),
		}, nil
	}

	return &ToolResult{
		ToolName:  toolName,
		Success:   true,
		Output:    output,
		Duration:  duration,
		Timestamp: time.Now(),
	}, nil
}

// GetExecutionStats 获取执行统计信息
func (e *Executor) GetExecutionStats() map[string]interface{} {
	return map[string]interface{}{
		"timeout": e.timeout.String(),
		"tools":   e.tools.GetToolNames(),
	}
}

// Close 关闭执行器
func (e *Executor) Close() error {
	// 清理资源
	log.Printf("[EXECUTOR] 🔄 执行器关闭")
	return nil
}
